package com.neusoft.neuiotms.dcom.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

import javax.persistence.EntityNotFoundException;

import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.bizcore.web.utils.EasyPoiExcelUtil;
import com.neusoft.neuiotms.common.dto.DictionaryDTO;
import com.neusoft.neuiotms.common.service.DictionaryService;
import com.neusoft.neuiotms.dcom.converter.HolidayConverter;
import com.neusoft.neuiotms.dcom.dto.HolidayDTO;
import com.neusoft.neuiotms.dcom.model.Holiday;
import com.neusoft.neuiotms.dcom.repository.HolidayRepository;
import com.neusoft.neuiotms.dcom.service.HolidayService;
import com.neusoft.neuiotms.dcom.vo.HolidayVO;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;

@Service
public class HolidayServiceImpl implements HolidayService {

    @Autowired
    private HolidayRepository holidayRepository;
    @Autowired
    private HolidayConverter holidayConverter;
    @Autowired
    private DictionaryService dictionaryService;

    @Override
    public List<HolidayDTO> index(final Searchable searchable) {
        final List<Holiday> result = this.holidayRepository.index(searchable);
        return this.holidayConverter.toListDTO(result);
    }

    @Override
    public Page<HolidayDTO> search(final Pageable pageable, final Searchable searchable) {
        final Page<Holiday> result = this.holidayRepository.search(pageable, searchable);
        return this.holidayConverter.toPageDTO(result);
    }

    @Override
    public HolidayDTO create(final HolidayDTO dto) {
        final Holiday model = this.holidayConverter.toModel(dto);
        this.holidayRepository.save(model);
        return this.holidayConverter.toDTO(model);
    }

    @Override
    public HolidayDTO update(final Long id, final HolidayDTO dto) {

        Holiday model;
        try {
            model = this.holidayRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        dto.setId(model.getId());
        model = this.holidayConverter.toModel(dto);
        this.holidayRepository.save(model);
        return this.holidayConverter.toDTO(model);
    }

    @Override
    public HolidayDTO details(final Long id) {

        Holiday model;
        try {
            model = this.holidayRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        return this.holidayConverter.toDTO(model);
    }

    @Override
    public void delete(final Long id) {
        this.holidayRepository.deleteById(id);
    }

    @Override
    public Workbook template() {

        final List<HolidayVO> list = new ArrayList<>();
        final Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("节假日模板", "节假日模板", ExcelType.XSSF),
                HolidayVO.class, list);

        //节假日类型
        final Searchable searchable = new Searchable();
        searchable.put("type", "holidayType");
        final List<DictionaryDTO> holidayTypes = this.dictionaryService.findAll(searchable);
        final List<String> typeConstraint =
                holidayTypes.stream().map(k -> k.getText() + "_" + k.getCode()).collect(Collectors.toList());

        final Iterator<Sheet> iterator = workbook.iterator();
        while (iterator.hasNext()) {
            final Sheet sheet = iterator.next();
            //类型列加下拉候选框
            EasyPoiExcelUtil.sheetConstraintXSSF(sheet, 1, 65535, 1, 1, typeConstraint);

        }
        return workbook;
    }

    @Override
    public void upload(final MultipartFile file) {

        final ImportParams params = new ImportParams();
        params.setTitleRows(1);
        params.setHeadRows(1);
        params.setNeedVerify(true);
        ExcelImportResult<HolidayVO> result = null;
        try {
            result = ExcelImportUtil.importExcelMore(file.getInputStream(), HolidayVO.class, params);
        } catch (final IOException e) {
            e.printStackTrace();
            throw new UnitedException("导入失败");
        } catch (final Exception e) {
            e.printStackTrace();
        }
        if ((result != null) && result.isVerifyFail()) {
            final List<HolidayVO> failList = result.getFailList();
            failList.forEach(l -> {
                throw new UnitedException("第" + (l.getRowNum() + 1) + "行," + l.getErrorMsg() + "! \n");
            });

        }
        final List<Holiday> models = new ArrayList<>();
        final List<HolidayVO> list = result.getList();

        list.stream().map(s -> this.holidayConverter.toModel(s)).filter(k -> null != k).forEach(models::add);

        if (!models.isEmpty()) {
            this.holidayRepository.saveAll(models);
        }

    }

}
